//	面积图
import React from 'react';
import { Area } from '@antv/g2plot';
import { data, MIN_MAX } from './mock';
import { getComponentData } from 'src/services/AnalyseManage';
import { WD_TYPE, DL_TYPE, THEME_COLOR } from 'src/pages/AnalyseManage/EditReport/components/EditorDataType/EnumConfig';
import { ChartService, IProps } from 'src/pages/AnalyseManage/EditReport/components/ChartsType/components/ChartService';
import { bigNumberTransform, digitFormat, isNumber } from 'src/libs/utils';
import { CHART_LINK } from 'src/pages/AnalyseManage/EditReport/topics';
import PubSub from 'pubsub-js';

export default class AreaChart extends ChartService {
	state = {
		chartEl: null,
		data: data,
		min_max: MIN_MAX,
		eventToken: [],
		dataUnit: [],
		dependencies: [],	//	图表联动参数
		isRender: false
	};

	initEvent = async () => {
		const { data, min_max, dataUnit } = await this.getConditionData();
		this.setState( { data, min_max, dataUnit }, () => {
			const area = new Area( this.props.id, this.getConfig() );
			area.render();
			console.log( area );
			this.setState( {
				chartEl: area,
				isRender: true
			} );

			//	数据联动 组装联动参数
			area.on( 'element:click', ( ev ) => {
				if( !this.props.config.mutual.isChainAvailable ) return;

				const intervalElement = ev.target.get( 'element' );
				const data = intervalElement.getModel().data; // 单条数据
				console.log( data );
				if( Object.prototype.toString.call( data ) === '[object Array]' ) return;
				let dimension = [];

				//	取x轴字段和颜色维度字段
				const tempArray = [
					{
						key: 'chartLineXColumns',
						itemKey: 'name'
					},
					{
						key: 'chartLineColorColumns',
						itemKey: 'category'
					}
				];

				tempArray.forEach( field => {
					let columns = this.props.config.data[field.key];
					if( columns && columns.length > 0 ) {
						dimension = dimension.concat( columns.map( ( item, index ) => {
							return {
								formatType: item.formatType,
								id: [ item.name ],
								quota: item.modelType === WD_TYPE ? 'WD' : 'DL',
								symbol: 'EQ',
								value: [ data[field.itemKey] ]		//	从原数据中找到item，一一对应字段
							};
						} ) );
					}
				} );

				if( dimension.length === 0 ) return;

				PubSub.publish( CHART_LINK, {
					publisherId: this.props.id,
					listenerIds: this.props.config.mutual.chartsChainIds,
					dimension: dimension,
					tableCode: this.props.config.data.tableCode
				} );
			} );
		} );
	};


	getSnapshotBeforeUpdate( prevProps: Readonly<IProps>, prevState: Readonly<{ dependencies: any }> ): any | null {
		let { config } = this.props;
		let changeObj = Object.create( null );

		//	判断数据字段是否变化了
		if ( JSON.stringify( prevProps.config.data ) !== JSON.stringify( config.data ) ||
			JSON.stringify( this.state.dependencies ) !== JSON.stringify( prevState.dependencies ) ) {
			changeObj.needDataChange = true;
		}

		//	判断样式是否改变
		if ( JSON.stringify( prevProps.config.data.chartLineYColumnsUnit ) !== JSON.stringify( config.data.chartLineYColumnsUnit ) ||
			 JSON.stringify( prevProps.config.style ) !== JSON.stringify( config.style ) ) {
			changeObj.needStyleChange = true;
		}

		return changeObj;
	}

	async componentDidUpdate( prevProps: Readonly<IProps>, prevState: Readonly<{}>, snapshot?: any ) {
		if ( snapshot.needStyleChange ) {
			this.state.chartEl.update( this.getConfig() );
		}
		if ( snapshot.needDataChange ) {
			// 更新数据
			const { data, min_max, dataUnit } = await this.getConditionData();
			this.setState( { data, min_max, dataUnit }, () => {
				this.state.chartEl.update( this.getConfig() );
				this.state.chartEl.changeData( data );
			} );
		}
		
	}

	getConfig = (): any => {
		let { style, data: dataConfigs } = this.props.config;
		// console.log( dataConfigs );
		return {
			data: this.state.data,
			xField: 'name',
			yField: 'value',
			seriesField: 'category',
			appendPadding: [
				style.chartTopPadding || 0,
				style.chartRightPadding || 0,
				style.chartBottomPadding || 0,
				style.chartLeftPadding || 0
			],
			meta: {
				name: {
					alias: style.chartXAxisName || 'name' ,
				},
				value: {
					alias: style.chartYAxisName || 'value' ,
					formatter: ( data ) => {
						return data;
					}
				},
			},
			autoFit: true,
			// 设置轴边距
			padding: 'auto',
			color: ( style.customBlockColor ? style.customBlockColor.map( ( v ) => v.color ) : [] ).concat( THEME_COLOR ),
			
			legend: style.isShowLegend === true ?  
				{
					position: style.legendPosition,
					itemName: {
						style: {
							fill: style.legendFontColor,
							fontSize: style.legendFontSize,
							fontFamily: style.legendFontFamily,
							fontWeight: style.legendFontBold ? 'bold' : 'normal',
							fontStyle: style.legendFontItalic ? 'italic' : 'normal',
						},
					},
				} : false
			,
			tooltip: this.getToolTipConfig( style ),
			xAxis: {
				tickCount: 15,
				line: style.isShowXLine
					? {
						style: {
							stroke: style.chartLineColor,
						},
					  }
					: null,
				title: style.isShowXLine && style.isShowXLineName
					? {
						offset: 30,
						style: {
							fontFamily: style.XLineFontFamily,
							fontSize: parseInt( style.XLineFontSize || 15 ),
							fontWeight: style.XLineFontBold ? 'bold' : 'normal',
							fontStyle: style.XLineFontItalic ? 'italic' : 'normal',
							fill: style.XLineFontColor || '#333',
						},
					}
					: null,
				tickLine: style.isShowXLine ? {} : null,
				label: {
					style: style.chartLineDataColor
						? {
							fill: style.chartLineDataColor,
							fontSize: style.isShowXLine ? 12 : 0,
						  }
						: {
							// 设置X轴不显示，设置axis为null不生效，需要设置不显示label,line, tickline
							fontSize: style.isShowXLine ? 12 : 0,
						  },
				  rotate: style.chartXAxisLabelTilt ? style.chartXAxisLabelTilt : 0,
				},
			},
			yAxis: {
				tickCount: 5,
				line: style.isShowYLine
					? {
						style: {
							stroke: style.chartLineColor,
						},
					  }
					: null,
				title: style.isShowYLineName
					? {
						style: {
							fontFamily: style.YLineFontFamily,
							fontSize: parseInt( style.YLineFontSize || 15 ),
							fontWeight: style.YLineFontBold ? 'bold' : 'normal',
							fontStyle: style.YLineFontItalic ? 'italic' : 'normal',
							fill: style.YLineFontColor || '#333',
						},
					  }
					: null,
				// 网格线样式
				grid: style.isHiddenYGridLine
					? null
					: {
						line: {
							style: {
								stroke: style.chartGridlineColor,
							},
						},
					  },
				// 设置坐标轴文字部分样式
				label: {
					style: style.chartLineDataColor
						? {
							fill: style.chartLineDataColor,
						  }
						: {},
					formatter: ( v ) => {
						v = bigNumberTransform( v );

						return `${ v }${dataConfigs.chartLineYColumnsUnit || ''}`;
					},
					// rotate: style.chartYAxisLabelTilt ? style.chartYAxisLabelTilt : 0,
				},
			},
			label: this.getLabelConfig( style ),
			// 设置标签
			point: this.getPointOptions( style ),
			annotations: this.getAnnotations( dataConfigs.areaType ),
			// color: '#a8ddb5',
		};
	};

	getLabelConfig = ( style ) => {
		const getLabelText = ( category, value, precision, dataUnit ) => {
			return this.getDataByDataUnit( category, value, precision, dataUnit ).value;
		};
		return style.isShowLabelData
			? {
				style: {
					fontFamily: style.labelFontFamily || 'none',
					fontSize: parseInt( style.labelFontSize || 15 ),
					fontWeight: style.labelFontBold ? 'bold' : 'normal',
					fontStyle: style.labelFontItalic ? 'italic' : 'normal',
					fill: style.labelFontColor || '#333',
				},
				formatter: ( data, c, d ) => {
					const { value, category, precision = '', dataUnit = '' } = data;
					if ( style.onlyShowLabelMax && value === this.state.min_max[category].max ) {
						return getLabelText( category, this.state.min_max[category].max, precision, dataUnit );
					} else if ( style.onlyShowLabelMin && value === this.state.min_max[category].min ) {
						return getLabelText( category, this.state.min_max[category].min, precision, dataUnit );
					} else if (
						( style.onlyShowLabelMax && value !== this.state.min_max[category].max ) ||
							( style.onlyShowLabelMin && value !== this.state.min_max[category].min )
					) {
						return null;
					}
					return getLabelText( category, value, precision, dataUnit );
				},
			  }
			: null;
	};

	// 设置数据单位
	getDataByDataUnit = ( category, value, precision = '', dataUnit = ''  ) => {
		value = isNumber( precision ) ? value.toFixed( precision ) : value;		//	小数尾数格式化
		value = digitFormat( value, 3 );				//	千分位格式化

		return {
			name: category,
			value: `${value}${dataUnit}`
		};
	};

	// 设置提示config
	getToolTipConfig = ( style ) => {
		const getToolTipLabel =  ( datum ) => {
			return this.getDataByDataUnit( datum.category, datum.value, datum.precision, datum.dataUnit );
		};
		return style.isShowToolTip
			? {
				showContent: true,
				// 设置toolTip相关样式
				domStyles: {
					'g2-tooltip-list-item': {
						fontSize: `${style.tooltipFontSize || '12'}px`,
						color: style.tooltipFontColor,
						fontFamily: style.tooltipFontFamily,
						fontWeight: style.tooltipFontBold ? 'bold' : 'normal',
						fontStyle: style.tooltipFontItalic ? 'italic' : 'normal',
					},
					'g2-tooltip-title': {
						fontSize: `${style.tooltipFontSize || '12'}px`,
						color: style.tooltipFontColor,
						fontFamily: style.tooltipFontFamily,
						fontWeight: style.tooltipFontBold ? 'bold' : 'normal',
						fontStyle: style.tooltipFontItalic ? 'italic' : 'normal',
					},
				},
				fields: [ 'name', 'value', 'category', 'precision', 'dataUnit' ],
				formatter: ( datum ) => {
					return getToolTipLabel( datum );
				},
			}
			: {
				showContent: false,
				domStyles: null,
			};
	};

	// 设置标签样式
	getPointOptions = ( style ) => {
		let config = {
			size: style.chartLabelMarkSize || 5,
			shape: style.chartLabelMarkType
				? style.chartLabelMarkType === 'hollowCircle'
					? 'circle'
					: style.chartLabelMarkType
				: 'circle',
			style: {
				fill: style.chartLabelMarkColor || '#5B8FF9',
				stroke: style.chartLabelMarkColor || '#5B8FF9',
				lineWidth: 2,
				fillOpacity: style.isShowLabelData ? 1 : 0,
				opacity: style.isShowLabelData ? 1 : 0
			},
		};
		// 如果是空心圆需要填充白色
		if ( style.chartLabelMarkType === 'hollowCircle' ) {
			config.style.fill = 'white';
		}
		// return style.isShowLabelData ? config : null;
		return config;
	};

	// 设置中位线
	getAnnotations = ( type ) => {
		if ( type === 'medianLine' ) {
			let config = [
				{
					type: 'text',
					position: [ 'min', 'median' ],
					content: '中位数',
					offsetY: -4,
					style: {
						textBaseline: 'bottom',
					},
				},
				{
					type: 'line',
					start: [ 'min', 'median' ],
					end: [ 'max', 'median' ],
					style: {
						stroke: '#FFBB22',
						lineDash: [ 2, 2 ],
					},
				},
			];
			return config;
		} else {
			return null;
		}
	};

	// 获取数据
	async getConditionData() {
		const { data: dataConfigs } = this.props.config;
		if (
			dataConfigs.chartLineXColumns &&
			dataConfigs.chartLineXColumns.length > 0 &&
			dataConfigs.chartLineYColumns &&
			dataConfigs.chartLineYColumns.length > 0
		) {
			const itemInfo = ( v, orderType?, desc? ) => {
				return {
					aggregateType: v.modelType === DL_TYPE ? v.aggregateType : '', //	度量的聚合类型
					formatType: v.modelType === WD_TYPE ? v.formatType : '', // 维度的聚合类型v.
					alias: v.title.trim(),
					dataType: v.dataType,
					frontendId: '',
					id: v.name,
					orderType: orderType || v.orderType, // 排序方式
					quota: v.modelType === WD_TYPE ? 'WD' : 'DL',
					symbol: '',
					type: v.type,
					value: '',
					dataUnit: v.dataUnit || '',
					precision: v.precision
				};
			};
			const x = dataConfigs.chartLineXColumns.map( ( v ) => {
				if ( v.dataType === 'datetime' ) {
					return itemInfo( v, 'ASC' );
				}
				return itemInfo( v );
			} );

			const y = dataConfigs.chartLineYColumns.map( ( v ) => {
				return itemInfo( v );
			} );

			const category = dataConfigs.chartLineColorColumns ? dataConfigs.chartLineColorColumns.map( ( v ) => {
				return itemInfo( v );
			} ) : [];

			// const conditions = this.props.config.data.filterFields ? this.props.config.data.filterFields.map( v => v.filterConditions ).flat() : [];
			// 内部筛选 condition
			const filterFieldCondition = this.props.config.data.filterFields
				? this.props.config.data.filterFields.map( ( v ) => v.filterConditions ).flat()
				: [];

			// 筛选组件的 condition
			let filterCompConditions = this.props.config.data.filterConditions || {};
			let newFilterCompConditions = [];
			Object.keys( filterCompConditions ).forEach( ( key ) => {
				newFilterCompConditions = newFilterCompConditions.concat( filterCompConditions[key] );
			} );

			const request = {
				dataConfig: {
					dataModel: {
						pageId: this.props.pageId,
						tableName: this.props.config.data.tableCode,
						x: x,
						y: y,
						category: category,
						conditions: filterFieldCondition.concat( this.state.dependencies, newFilterCompConditions )
					},
					needAutoRefresh: true,
					tableType: 'area',
				},
				type: 'line',
				tenantCode: this.props.tenantCode
			};

			let pageResponse = await getComponentData( request );
			if ( pageResponse.data && pageResponse.data.success ) {
				const { extra, rows = [] } = pageResponse.data.data;
				// const newRows = transformDataUnitData( rows, y, 'value' );

				return { data: rows, min_max: extra.maxmin, dataUnit: ( extra && extra.dataUnit ) || [] };
			}
		}

		return { data, min_max: MIN_MAX, dataUnit: [] };
	}

	render() {

		return <div id={this.props.id} style={{ height: '100%' }}></div>;
	}
}
